home *** CD-ROM | disk | FTP | other *** search
- // Spirograph simulator for 640x480 VGA mono
- // Borland C++ source
- // Need to add in the EGAVGA BGI driver to your graphics.lib
- // using bin2obj and then tlib
- //
- /******************************************************
- Nigel Salt
- 25 Lower Station Rd
- Crayford
- Kent
- DA1 3PY
- UK
-
- Phone +44 322 553260
-
- Email nao@cix.complink.co.uk
- ******************************************************/
-
-
- #include <graphics.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <conio.h>
- #include <math.h>
- #include <ctype.h>
- #include <dos.h>
-
- void initsin(void);
- void initparm(void);
- int getint3xy(int x, int y, char far *prompt);
- int getchxy(int x, int y, char far *prompt);
- void spiro(void);
- void setdrawport(void);
- void setstatport(void);
- void printstatus(void);
- void getpx(void);
- void getpy(void);
- void getpxr1(void);
- void getpyr1(void);
- void getpinorout(void);
- void getpr2(void);
- void getpr3(void);
- void getpinc(void);
- int getparm(void);
- void highopt(int opt);
- void unhighopt(int opt);
- void writeopt(int opt);
- int xgetch(void);
-
- #define PI (3.141592654)
- #define IN (-1)
- #define OUT (1)
- #define UNITSINCIRC (4000)
- #define GO 1
- #define STOP 0
- #define RIGHTKEY 256*77
- #define LEFTKEY 256*75
- #define SHIFTAB 256*15
- #define ESC 27
- #define SINMULT (0x100000L)
- #define MODMULT (0x100000L)
- long sintab[UNITSINCIRC+1];
- int x=320,
- y=235,
- xr1=100,
- yr1=100,
- r2=35,
- r3=35,
- inc=10,
- flag=IN;
- char inorout;
- double modulus;
-
-
- int main(void)
- {
- /* request auto detection */
- int gdriver = DETECT, gmode, errorcode;
- int parmret;
-
- /* register a driver that was added into graphics.lib */
- /* For information on adding the driver, see the
- /* BGIOBJ section of UTIL.DOC */
- errorcode = registerbgidriver(EGAVGA_driver);
-
- /* report any registration errors */
- if (errorcode < 0)
- {
- printf("Graphics error: %s\n", grapherrormsg(errorcode));
- printf("Press any key to halt:");
- getch();
- exit(1); /* terminate with an error code */
- }
- initsin();
-
- /* initialize graphics and local variables */
- initgraph(&gdriver, &gmode, "");
-
- /* read result of initialization */
- errorcode = graphresult();
- if (errorcode != grOk) /* an error occurred */
- {
- printf("Graphics error: %s\n", grapherrormsg(errorcode));
- printf("Press any key to halt:");
- getch();
- exit(1); /* terminate with an error code */
- }
-
- /* draw a line */
- line(0, 470, getmaxx(), 470);
- /* initparm();
- spiro();
- */
- printstatus();
- parmret=getparm();
- while (parmret!=STOP)
- {
- spiro();
- printstatus();
- parmret=getparm();
- };
- /* clean up */
- closegraph();
- return 0;
- }
-
- void initsin(void)
- {
- int i;
- int dotcount=100;
- double inc=2*PI/UNITSINCIRC;
- double ang=0;
- printf("Initialising SIN table");
- for (i=0;i<UNITSINCIRC;i++)
- {
- sintab[i]=sin(ang)*SINMULT;
- ang+=inc;
- dotcount--;
- if (dotcount<0)
- {
- dotcount=100;
- printf(".");
- };
- };
- };
-
- void initparm(void)
- {
- getpx();
- getpy();
- getpxr1();
- getpyr1();
- getpinorout();
- getpr2();
- getpr3();
- getpinc();
- };
-
- void highopt(int opt)
- {
- setcolor(LIGHTRED);
- writeopt(opt);
- };
-
- void unhighopt(int opt)
- {
- setcolor(WHITE);
- writeopt(opt);
- };
-
- void writeopt(int opt)
- {
- switch (opt)
- {
- case 0:
- moveto(0,0);
- outtext("GO");
- break;
- case 1:
- moveto(24,0);
- outtext("EXIT");
- break;
- case 2:
- moveto(64,0);
- outtext("CLS");
- break;
- case 3:
- moveto(96,0);
- outtext("XC:");
- break;
- case 4:
- moveto(152,0);
- outtext("YC:");
- break;
- case 5:
- moveto(208,0);
- outtext("XRS:");
- break;
- case 6:
- moveto(272,0);
- outtext("YRS:");
- break;
- case 7:
- moveto(336,0);
- if (flag==IN)
- outtext("IN ");
- else
- outtext("OUT");
- break;
- case 8:
- moveto(368,0);
- outtext("RAD:");
- break;
- case 9:
- moveto(432,0);
- outtext("PEN:");
- break;
- case 10:
- moveto(496,0);
- outtext("INC");
- break;
- default:
- break;
- };
- };
-
- int getparm(void)
- {
- int inch,go,stop;
- int curopt;
- setstatport();
- highopt(0);
- curopt=0;
- go=0;
- stop=0;
- while (!go&&!stop)
- {
- while (!kbhit())
- {
- highopt(curopt);
- delay(100);
- unhighopt(curopt);
- delay(100);
- };
- inch=xgetch();
- switch (inch)
- {
- case ESC:
- return STOP;
- case SHIFTAB:
- case LEFTKEY:
- printstatus();
- curopt--;
- if (curopt<0) curopt=10;
- highopt(curopt);
- break;
- case '\t':
- case ' ':
- case RIGHTKEY:
- printstatus();
- curopt++;
- if (curopt>10) curopt=0;
- highopt(curopt);
- break;
- case '\r':
- setstatport();
- clearviewport();
- switch (curopt)
- {
- case 0:
- return GO;
- case 1:
- return STOP;
- case 2:
- setdrawport();
- clearviewport();
- setstatport();
- break;
- case 3:
- getpx();
- break;
- case 4:
- getpy();
- break;
- case 5:
- getpxr1();
- break;
- case 6:
- getpyr1();
- break;
- case 7:
- getpinorout();
- break;
- case 8:
- getpr2();
- break;
- case 9:
- getpr3();
- break;
- case 10:
- getpinc();
- break;
- default:
- break;
- };
- printstatus();
- highopt(curopt);
- break;
- default:
- break;
-
- };
- };
-
- moveto(0,0);
- setcolor(WHITE);
- outtext("GO");
- return GO;
- };
-
- void getpx(void)
- {
- x=-1;
- while (x<1||x>getmaxx())
- x=getint3xy(0,472,"XCOORD OF CENTRE (0-639): ");
- };
-
- void getpy(void)
- {
- y=-1;
- while (y<1||y>469)
- y=getint3xy(0,472,"YCCORD OF CENTRE (0-469): ");
- };
-
- void getpxr1(void)
- {
- xr1=-1;
- while (xr1<1||xr1>getmaxx())
- xr1=getint3xy(0,472,"X RADIUS OF STILL OVAL: ");
- };
-
- void getpyr1(void)
- {
- yr1=-1;
- while (yr1<1||yr1>469)
- yr1=getint3xy(0,472,"Y RADIUS OF STILL OVAL: ");
- };
-
- void getpinorout(void)
- {
- inorout='x';
- flag=IN;
- while (inorout!='I'&&inorout!='O')
- inorout=toupper(getchxy(0,472,"MOVE INSIDE OR OUT (I/O): "));
- if (inorout=='O') flag=OUT;
- };
-
- void getpr2(void)
- {
- r2=-1;
- while (r2<1||r2>getmaxx())
- r2=getint3xy(0,472,"RADIUS OF MOVING CIRCLE: ");
- };
-
- void getpr3(void)
- {
- r3=-1;
- while (r3<1||r3>getmaxx())
- r3=getint3xy(0,472,"PEN POSITION: ");
- };
-
- void getpinc(void)
- {
- inc=-1;
- while (inc<1||inc>999)
- inc=getint3xy(0,472,"INCREMENT: ");
-
- };
-
- int getint3xy(int x, int y, char far *prompt)
- {
- int inch,retval,numlen;
- char buff[5];
- struct viewporttype oldvp;
- getviewsettings(&oldvp);
- setviewport(x,y,getmaxx()-1,y+7,1);
- numlen=0;
- retval=0;
- inch='\0';
- buff[1]='\0';
- outtext(prompt);
- while (inch!='\r'&&numlen<4)
- {
- inch=getch();
- if (inch<'0'||inch>'9') continue;
- retval*=10;
- retval+=inch-'0';
- numlen++;
- buff[0]=inch;
- outtext(buff);
- };
- clearviewport();
- setviewport(oldvp.left,oldvp.top,oldvp.right,oldvp.bottom,oldvp.clip);
-
- return retval;
- };
-
- int getchxy(int x, int y, char far *prompt)
- {
- int inch,retval;
- struct viewporttype oldvp;
- getviewsettings(&oldvp);
- setviewport(x,y,getmaxx()-1,y+7,1);
- outtext(prompt);
- retval=getch();
- clearviewport();
- setviewport(oldvp.left,oldvp.top,oldvp.right,oldvp.bottom,oldvp.clip);
- return retval;
- };
-
- void spiro(void)
- {
- long rots;
- double modulus;
- long x1mult, x2mult, y1mult, y2mult;
- long avr1,ang1;
- unsigned long total, uli, progmax, progcur, proglin;
- int ang;
- int posx, posy;
- progcur=0;
- proglin=0;
- avr1=(xr1+yr1+.5)/2;
- modulus=-(xr1+yr1)/2;
- modulus/=r2;
- rots=1;
- /* Find smallest number of rotations that is more or less exactly
- divisible by the radius of the moving circle */
- while ((rots*avr1)%r2>0)
- rots++;
- total=UNITSINCIRC*rots;
- progmax=total/20;
- setdrawport();
- x1mult=xr1+(flag*r2);
- x2mult=flag*r3;
- y1mult=yr1+(flag*r2);
- y2mult=flag*r3;
- for (uli=0;uli<total;uli+=inc, progcur+=inc)
- {
- if (kbhit()) break;
- if (progcur>progmax)
- {
- setstatport();
- setfillstyle(SOLID_FILL,EGA_LIGHTRED);
- bar(proglin*32,1,(proglin+1)*32,8);
- proglin++;
- progcur=0;
- setdrawport();
- };
- ang1=uli*modulus;
- ang1%=UNITSINCIRC;
- if (ang1<0) ang1+=UNITSINCIRC;
- ang=(int)(uli%UNITSINCIRC);
-
- /* Calculate xpos */
- posx=x;
- posx+=(int)((sintab[ang]*x1mult)/SINMULT);
- posx-=(int)((x2mult*sintab[ang1])/SINMULT);
-
- /* Add one quarter rotation for cosine */
- ang=(ang+UNITSINCIRC/4)%UNITSINCIRC;
- ang1=(ang1+UNITSINCIRC/4)%UNITSINCIRC;
-
- /* Calculate ypos */
- posy=y;
- posy+=(int)((sintab[ang]*y1mult)/SINMULT);
- posy-=(int)((y2mult*sintab[ang1])/SINMULT);
-
- putpixel(posx,posy,15);
- };
-
-
- };
-
- void setdrawport(void)
- {
- setviewport(0,0,639,469,1);
- };
-
- void setstatport(void)
- {
- setviewport(0,472,639,479,1);
- };
-
-
- void printstatus(void)
- {
- char buffer[81];
- char inoutbuf[10];
- setcolor(WHITE);
- if (flag==IN)
- sprintf(inoutbuf,"IN ");
- else
- sprintf(inoutbuf,"OUT");
- setstatport();
- clearviewport();
- sprintf(buffer,
- "GO EXIT CLS XC:%3d YC:%3d XRS:%3d YRS:%3d %s RAD:%3d PEN:%3d INC:%3d",
- x,y,xr1,yr1,inoutbuf,r2,r3,inc);
- outtext(buffer);
- };
-
- int xgetch(void)
- {
- int retkey;
- retkey=getch();
- if (retkey>0) return retkey;
- retkey=256*getch();
- return retkey;
- }
-